/*******************************************************************************

  Pilot Intelligence Library
    http://www.pilotintelligence.com/

  ----------------------------------------------------------------------------

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.

*******************************************************************************/


#include "Svar_Table.h"


using namespace std;
using namespace sv;

SvarTable::SvarTable(QWidget *parent,Svar &svar_ins)
    : QTableWidget(parent), m_svar(svar_ins)
{
    setObjectName((QString::fromUtf8("SvarTable")));

    setColumnCount(3);
    setColumnWidth(0, 60);
    setColumnWidth(1, 270);
    setColumnWidth(2, 440);

    QStringList slHeader;
    slHeader.append("Type");
    slHeader.append("Name");
    slHeader.append("Value");
    setHorizontalHeaderLabels(slHeader);

    connect(this, SIGNAL(cellChanged(int,int)),
            this, SLOT(act_cellChanged(int,int)));

    load();
}

void SvarTable::setValue(int row,int col,QString val)
{
    if(item(row,col)!=NULL)
    {
        item(row,col)->setText(val);
    }
    else
    {
        QTableWidgetItem* item=new QTableWidgetItem();
        item->setText(val);
        setItem(row,col,item);
    }
}

void SvarTable::load(std::list<SvarElement>& sl)
{
    sl.sort([](const SvarElement& a, const SvarElement& b) {
            return a.name < b.name;
        });

    setRowCount(sl.size());
    int row=0;
    loading_flag=true;

    //int r,g,b;
    for(list<SvarElement>::iterator it=sl.begin();it!=sl.end();it++,row++)
    {
        const SvarElement& ele=*it;
        setValue(row,0,ele.type);
        setValue(row,1,ele.name);
        setValue(row,2,ele.value);
        if(m_svar.exist(ele.name.toStdString()))
            item(row,0)->setBackground(QBrush(QColor(50,255,50)));
        if(modified.count(ele.name))
            item(row,1)->setBackground(QBrush(QColor(0,255,255)));
        item(row,0)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable );//|
        item(row,1)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable );//|Qt::ItemIsEditable
    }
    loading_flag=false;
}

void SvarTable::load(QString filt_string)
{
    clearContents();
    std::list<SvarElement> sl;
    static std::set<std::string> ignore_names = {"__builtin__","argc","argv","__name__"};
    for(std::pair<std::string,Svar> it:m_svar) {
        if(ignore_names.count(it.first)) continue;

        const QString& name=QString::fromStdString(it.first);
        if( filt_string.size() > 0 )
            if(name.indexOf(filt_string,0,Qt::CaseInsensitive)<0) continue;

        std::stringstream sst;
        sst << it.second;
        sl.push_back(SvarElement(QString::fromStdString(it.second.typeName()),
                                 name,
                                 QString::fromStdString(sst.str())));
    }

    load(sl);
}

void SvarTable::act_cellChanged(int row, int column)
{
    (void) column;

    if(loading_flag) return;
    if(!(item(row,0)&&item(row,1)&&item(row,2))) return;
    const string& type=item(row,0)->text().toStdString();
    const string& name=item(row,1)->text().toStdString();
    if(name=="") return ;
    bool ok=false;
    if(type == "int"){
        int value=item(row,2)->text().toInt(&ok);
        if(ok)
            m_svar[name]=value;
    }
    if(type == "double"){
        double value=item(row,2)->text().toDouble(&ok);
        if(ok)
            m_svar[name]=value;
    }
    if(type == "str"){
        string value=item(row,2)->text().toStdString();
        ok = true;
        m_svar[name]=value;
    }
    if(!ok)
        item(row,2)->setBackground(QColor(0xFF,0,0));

//    else if(type=="Svar")
//    {
//        if(!m_svar.exist(name)) return ;
//        string value=item(row,2)->text().toStdString();
//        m_svar.insert(name,value,true);
//    }
//    else return;
    modified.insert(item(row,1)->text());
    item(row,1)->setBackground(QColor(0,255,255));
}

SvarWidget::SvarWidget(QWidget *parent,Svar &svar_ins)
    :QWidget(parent), m_table(this,svar_ins)
{
    setupUI();
}

void SvarWidget::setupUI()
{
    // set widget
    setWindowTitle("Svar Editor");
    setMinimumSize(850, 700);

    //botton pannel
    QWidget *btnPannel = new QWidget(this);
    btnPannel->setMinimumSize(QSize(100,40));

    QLabel *labFilter = new QLabel(btnPannel);
    labFilter->setObjectName(QString::fromUtf8("labFilter"));
    labFilter->setGeometry(QRect(20, 11, 37, 16));
    labFilter->setText("Filter:");

    m_edtFilter = new QLineEdit(btnPannel);
    m_edtFilter->setObjectName(QString::fromUtf8("edtFilter"));
    m_edtFilter->setGeometry(QRect(58, 6, 330, 27));
    m_edtFilter->setFocus();

    QPushButton* m_btnLoad = new QPushButton(btnPannel);
    m_btnLoad->setObjectName(QString::fromUtf8("btnLoad"));
    m_btnLoad->setGeometry(QRect(400, 6, 85, 27));
    m_btnLoad->setText("Refresh");
    m_btnLoad->setToolTip("Reload variables");

//    QPushButton* m_btnSave = new QPushButton(btnPannel);
//    m_btnSave->setObjectName(QString::fromUtf8("btnSave"));
//    m_btnSave->setGeometry(QRect(602, 6, 85, 27));
//    m_btnSave->setText("Save");
//    m_btnSave->setToolTip("Save to file");


    // vbox layout
    QVBoxLayout *verticalLayout = new QVBoxLayout(this);

    verticalLayout->addWidget(btnPannel);
    verticalLayout->addWidget(&m_table);

    // setup signals/slots
    connect(m_btnLoad, SIGNAL(clicked(bool)),
            this, SLOT(btnLoad_clicked(bool)));
    connect(m_edtFilter, SIGNAL(editingFinished()),
            this, SLOT(edtFilter_editingFinished()));
}

void SvarWidget::btnLoad_clicked(bool checked)
{
    (void) checked;

    edtFilter_editingFinished();
    m_table.hasFocus();
}

void SvarWidget::edtFilter_editingFinished(void)
{
    QString text=m_edtFilter->text();
    int index = text.indexOf('=');
    if (index > 0) {
        QString key = text.left(index).trimmed();
        QString value = text.mid(index + 1).trimmed();

        bool ok;
        double v = value.toDouble(&ok);
        if (!ok) {  // String
            svar[key.toStdString()] = value.toStdString();
        } else {
            if (v == (int)v) { // int
                svar[key.toStdString()] = (int)v;
            } else {  // double
                svar[key.toStdString()] = v;
            }
        }

        m_edtFilter->setText("");
        text = "";
    }

    m_table.load(text);
}
